#ifndef QUERYPLAN_H_
#define QUERYPLAN_H_

#include <set>
#include <limits>
#include "QueryPlanNode.h"

using namespace std;

class relation {
    private:
        char *rname;
        char *prefix;
        char rpath[100];
        Schema *rschema;
    public:
        relation (char *_name, Schema *_schema, char *_prefix) :
            rname (_name), rschema (_schema), prefix (_prefix) {
            sprintf (rpath, "%s%s.bin", prefix, rname);
        }
        char* name () { return rname; }
        char* path () { return rpath; }
        Schema* schema () { return rschema;}
};

class QueryPlan
{
	QueryPlanNode *root;
	Statistics stats;
    const char *settings = "test.cat";
    char *catalog_path, *dbfile_dir, *stats_path, *tpch_dir = NULL;
    map<string, relation *> tblsSchema;
    relation *s, *p, *ps, *n, *li, *r, *o, *c;
    relation *R[10], *R1[10];
    int pipeCount = 0;

    public:
        QueryPlan(int opt);
        ~QueryPlan();
        map<string,AndList*> tableCNFs;
        map<string,OrList*> joinAtts;
        set<string> joinTables;
        set<string> tableSets;
        void ProcessAndList();
        void Print(QueryPlanNode *p);
        void ExecuteTree(QueryPlanNode *p);
        void WaitUntilDone(QueryPlanNode *p);
        void LoadStats(char *statsFile, char *relNames[], int numTuples);
        void Setup(char *tables[], char *aliases[], int numTables);
        void Clean(QueryPlanNode *p);
        QueryPlanNode * PlannerDP();
        QueryPlanNode * Planner();
        QueryPlanNode * GetOptimalPlan();
};

#endif

